/*
 * Copyright (c) 2025 Huawei Device, Inc. Ltd. and <马弓手>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "GeolocationPlugin.h"
#include "cJSON.h"
#include "translateWgs.h"

REGISTER_PLUGIN_CLASS(GeolocationPlugin)

string GeolocationPlugin::coolType_bd09ll = "bd09ll";
string GeolocationPlugin::coolType_gcj02 = "gcj02";
string GeolocationPlugin::coolType_wgs84 = "wgs84";

bool GeolocationPlugin::execute(const string&  action, cJSON* args, CallbackContext cbc)
{
    if(action == "getCurrentPosition") {
        m_cbc = cbc;
        m_strCoolType = coolType_gcj02;
        cJSON* pOption = cJSON_GetArrayItem(args, 0);
        cJSON* pCoolType = cJSON_GetObjectItem(pOption, "coorType");
        if(pCoolType != NULL) {
            m_strCoolType = pCoolType->valuestring;
        }
        getLocation(cbc);
    }
    
    if(action == "watchPosition") {
        m_cbc = cbc;
        m_strCoolType = coolType_gcj02;
        cJSON* pOption = cJSON_GetArrayItem(args, 0);
        cJSON* pCoolType = cJSON_GetObjectItem(pOption, "coorType");
        if(pCoolType != NULL) {
            m_strCoolType = pCoolType->valuestring;
        }
        getLocation(cbc);
    }
    
    if(action == "clearWatch") {
        cbc.success();
    }
    
    if(action == "openFrontLocationService") {
    }
    
    if(action == "closeFrontLocationService") {
    }
    
    if(action == "onArKTsResult") {
        return onArKTsResult(args);
    }
    return true;
}

void GeolocationPlugin::getLocation(CallbackContext cbc)
{
    executeArkTs("/pages/GetCurrentPosition", 0, "", "BaiduGeolocation", cbc);
}

bool GeolocationPlugin::onArKTsResult(cJSON* args)
{
    cJSON* json = cJSON_GetObjectItem(args, "result");
    if(json != NULL && json->type == cJSON_Array) {
        int count = cJSON_GetArraySize(json);
        if(count > 0) {
            string result = cJSON_GetArrayItem(json,0)->valuestring;
            
            if(result == "OK") {
                string addr = cJSON_GetArrayItem(json,1)->valuestring;
                
                cJSON* content = cJSON_GetObjectItem(args, "content");
                
                cJSON* pContent = cJSON_Parse(content->valuestring);
                
                double latitude = 0.0;
                cJSON* pLatitude = cJSON_GetObjectItem(pContent, "latitude");
                if(pLatitude != NULL) {
                    latitude = pLatitude->valuedouble;
                }
                
                double longitude = 0.0;    
                cJSON* pLongitude = cJSON_GetObjectItem(pContent, "longitude");  
                if(pLongitude != NULL) {
                    longitude = pLongitude->valuedouble;
                }
                
                double altitude = 0.0;    
                cJSON* pAltitude = cJSON_GetObjectItem(pContent, "altitude");  
                if(pAltitude != NULL) {
                    altitude = pAltitude->valuedouble;
                } 
                    
                double accuracy = 0.0;    
                cJSON* pAccuracy = cJSON_GetObjectItem(pContent, "accuracy");  
                if(pAccuracy != NULL) {
                    accuracy = pAccuracy->valuedouble;
                }
                    
                double speed = 0.0;    
                cJSON* pSpeed = cJSON_GetObjectItem(pContent, "speed");  
                if(pSpeed != NULL) {
                    speed = pSpeed->valuedouble;
                }     
                
                double timeStamp = 0.0;    
                cJSON* pTimeStamp = cJSON_GetObjectItem(pContent, "timeStamp");  
                if(pTimeStamp != NULL) {
                    timeStamp = pTimeStamp->valuedouble;
                }    
                    
                double direction = 0.0;    
                cJSON* pDirection = cJSON_GetObjectItem(pContent, "direction");  
                if(pDirection != NULL) {
                    direction = pDirection->valuedouble;
                }
                
                double timeSinceBoot = 0.0;    
                cJSON* pTimeSinceBoot = cJSON_GetObjectItem(pContent, "timeSinceBoot");  
                if(pTimeSinceBoot != NULL) {
                    timeSinceBoot = pTimeSinceBoot->valuedouble;
                }
                
                double altitudeAccuracy = 0.0;    
                cJSON* pAltitudeAccuracy = cJSON_GetObjectItem(pContent, "altitudeAccuracy");  
                if(pAltitudeAccuracy != NULL) {
                    altitudeAccuracy = pAltitudeAccuracy->valuedouble;
                }
                    
                cJSON* extra = cJSON_Parse(addr.c_str());
                cJSON_AddNumberToObject(extra, "type", 61);
                cJSON_AddNumberToObject(extra, "gpsAccuracyStatus", 1); 
                cJSON* placeName = cJSON_GetObjectItem(extra, "placeName");
                if(placeName != NULL) {
                    cJSON_AddStringToObject(extra, "addr", placeName->valuestring); 
                }
                    
                cJSON* plat = cJSON_GetObjectItem(extra, "latitude");
                if(plat != NULL) {
                    cJSON_DeleteItemFromObject(extra,"latitude");
                }
                    
                cJSON* plong = cJSON_GetObjectItem(extra, "longitude");
                if(plong != NULL) {
                    cJSON_DeleteItemFromObject(extra,"longitude");
                }
               
                if(m_strCoolType == coolType_gcj02) {
                    translateWgs::wgs84ToGcj02(latitude, longitude, latitude, longitude);
                }
                if(m_strCoolType == coolType_bd09ll) {
                    translateWgs::wgs84ToGcj02(latitude, longitude, latitude, longitude);
                    translateWgs::gcj02toBd09(longitude, latitude, longitude, latitude);
                }    
                    
                cJSON*  coords = cJSON_CreateObject(); 
                cJSON_AddNumberToObject(coords, "latitude", latitude);
                cJSON_AddNumberToObject(coords, "longitude", longitude);
                cJSON_AddNumberToObject(coords, "altitude", altitude);
                cJSON_AddNumberToObject(coords, "accuracy", accuracy);
                cJSON_AddNumberToObject(coords, "altitudeAccuracy", altitudeAccuracy);
                cJSON_AddNumberToObject(coords, "heading", direction);
                cJSON_AddNumberToObject(coords, "speed", speed);
                
                cJSON*  position = cJSON_CreateObject();  
                cJSON_AddNumberToObject(position, "timestamp", timeStamp);
                cJSON_AddItemToObject(position, "coords", coords);
                
                cJSON* pResult = cJSON_CreateArray();
                cJSON_AddItemToArray(pResult, position);
                cJSON_AddItemToArray(pResult, extra);
                m_cbc.success(pResult);
                cJSON_Delete(pResult);
                cJSON_Delete(pContent);
            }
        }
    }
    return true;
}


